package com.ev.apis.controller.custom;


import com.alibaba.fastjson.JSONObject;
import com.ev.common.jobs.BackupsDBJob;
import com.ev.custom.domain.NoticeDO;
import com.ev.custom.vo.BackUpDBVO;
import com.ev.custom.vo.NoticeEntity;
import com.ev.framework.annotation.EvApiByToken;
import com.ev.framework.utils.*;
import com.ev.hr.domain.JobDO;
import com.ev.hr.service.JobService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.AbstractJavaTypeMapper;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 数据备份
 * </p>
 *
 * @author gumingjie.qi@gmail.com
 * @since 2020-06-04
 */
@RestController
@Api(value = "/", tags = "数据备份")
@Slf4j
public class BackUpDBController {
    private static final String CLASS_NAME = "com.ev.common.jobs.BackupsDBJob";
    private static final String DESCRIPTION = "数据备份";
    @Autowired
    private JobService jobService;
//    @Autowired
//    private MessageSourceHandler messageSourceHandler;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private Environment env;

    @EvApiByToken(value = "/apis/backUpDB/save", method = RequestMethod.POST)
    @ApiOperation(value = "保存数据备份定时任务")
    public R addJob(@Valid @RequestBody @ApiParam("保存数据备份定时任务") BackUpDBVO backUpDB) {
        // 解析cron 表达式
        int type = backUpDB.getType();
        int num = backUpDB.getNum();
        String cronExpression = "";
        TaskScheduleModel taskScheduleModel = new TaskScheduleModel();
        taskScheduleModel.setSecond(0);
        taskScheduleModel.setMinute(0);
        // 若是小时
        if (type == 0) {
            if (num < 0 || num > 23) {
                num = 23;
            }
            taskScheduleModel.setHour(num);
            taskScheduleModel.setJobType(0);
            cronExpression = CronUtil.createCronExpression(taskScheduleModel);
        }
        // 若是天
        if (type == 1) {
            if (num < 0 || num > 28) {
                num = 28;
            }
            taskScheduleModel.setHour(0);
            taskScheduleModel.setDay(num);
            taskScheduleModel.setJobType(1);
            cronExpression = CronUtil.createCronExpression(taskScheduleModel);
        }
        boolean isUpdate = false;

        JobDO jobDO = new JobDO();
        Map<String, Object> map = Maps.newHashMap();
        map.put("jobClassName", CLASS_NAME);
        List<JobDO> list = jobService.list(map);
        if (list.size() > 0) {
            jobDO = list.get(0);
            isUpdate = true;
        }
        boolean windows = OSinfo.isWindows();
        String filePath = windows ? env.getProperty("backups.db.winFilePath") : env.getProperty("backups.db.linuxFilePath");
        String[] parameterArray = {String.valueOf(type), String.valueOf(num), filePath};
        String parameter = StringUtils.join(parameterArray, ",");
        // 保存数据备份定时任务
        jobDO.setStatus(0);
        jobDO.setName(DESCRIPTION);
        jobDO.setCronExpression(cronExpression);
        jobDO.setDescription(DESCRIPTION);
        jobDO.setJobClassName(CLASS_NAME);
        jobDO.setParameter(parameter);
        if (isUpdate) {
            jobService.update(jobDO);
        } else {
            jobService.save(jobDO);
        }

        return R.ok();
    }


    @EvApiByToken(value = "/apis/backUpDB/detail", method = RequestMethod.POST)
    @ApiOperation(value = "查看数据备份定时任务")
    public R backUpDBDetail() {
        Map<String, Object> result = Maps.newHashMap();
        Map<String, Object> map = Maps.newHashMap();
        map.put("jobClassName", CLASS_NAME);
        List<JobDO> list = jobService.list(map);
        if (list.size() > 0) {
            JobDO jobDO = list.get(0);
            String parameter = jobDO.getParameter();
            String[] split = parameter.split(",");
            map.put("type", Integer.parseInt(split[0]));
            map.put("num", Integer.parseInt(split[1]));
            map.put("filePath", split[2]);
            result.put("data", map);
        }
        return R.ok(result);
    }

    @EvApiByToken(value = "/apis/backUpDB/copyNow", method = RequestMethod.POST)
    @ApiOperation(value = "立即备份")
    public R copyNow() throws JsonProcessingException {
        //1.保存消息主体信息
        NoticeEntity noticeEntity = new NoticeEntity();
        NoticeDO notice =new NoticeDO();
        notice.setTitle("数据备份错误");
        notice.setContent("数据库备份失败,请查看系统日志,或联系管理员");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("url","#");
        notice.setContentDetail(jsonObject.toJSONString());
        //2.保存消息关联用户
        noticeEntity.setNoticeDO(notice);
        List<Long> toUsers = Lists.newArrayList();
        toUsers.add(ShiroUtils.getUserId());
        noticeEntity.setToUserList(toUsers);

        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        rabbitTemplate.setExchange("gyhl.data.db.exchange");
        rabbitTemplate.setRoutingKey("gyhl.data.db.routing.key");
        Message messageObj = MessageBuilder.withBody(objectMapper.writeValueAsBytes(noticeEntity)).setDeliveryMode(MessageDeliveryMode.PERSISTENT).build();
        messageObj.getMessageProperties().setHeader(AbstractJavaTypeMapper.DEFAULT_CONTENT_CLASSID_FIELD_NAME, MessageProperties.CONTENT_TYPE_JSON);
//        rabbitTemplate.convertAndSend(messageObj);

        boolean success = BackupsDBJob.backUpDB(env);
        return R.ok();
    }


}

